Component.php

<?php

namespace Fresh;

class Component {

    protected $dir;
    protected $name;
    protected $viewQueries = [];
    protected $formQueries = [];
    protected $submitHandler;
    protected $filterHandler;

    static protected $views = [];

    public function __construct($name = null,$dir = null){
        $this->dir = $dir ?? $this->dir;
        $this->name = $name ?? $this->name;

        // $this->setupCompo();
        // $this->compileViews();
        // var_dump($this->dir);
        // exit;
        // $this->submitHandler = [$this,'saveData'];
    }

    public function viewNames(){
        $viewPath = $this->dir.'/View.php';
        if (file_exists($viewPath))return ['View'];
        if (is_dir($this->dir.'/View/')){
            throw new \Exception("We don't handle multiple views yet.");
        }

        throw new \Exception("No views found.");
    }
    public function view($view=null,$passthru=[]){
        if ($view==null)$view="View";

        $file = $this->dir.'/'.$view.'.php';
        $existing = static::$views[$file] ?? null;
        if ($existing!=null){
            $existing->setPassthru($passthru);
            return $existing;
        }

        $viewObj = new View($file,$view,$passthru);
        static::$views[$file] = $viewObj;


        return $viewObj;
    }

    public function form($view='',$passthru=[]){
        if ($view=='View')$view='';
        $view .= 'Form';

        $file = $this->dir.'/'.$view.'.php';
        $existing = static::$views[$file] ?? null;
        if ($existing!=null){
            $existing->setPassthru($passthru);
            return $existing;
        }

        $formObj = new \FreshForm($file,$view,$passthru);
        static::$views[$file] = $formObj;


        return $formObj;
    }

    public function filter($name,$value,$input){

        $filterererererer = $this->filterHandler;
        if ($filterererererer==null)return $value;
        else {
            $filteredededValue = $filterererererer($name,$value,$input);
            return $filteredededValue;
        }
    }
    public function submit($formName,$passthru=[],$submitData=null){
//TODO how do file uploads work with this abstraction?
        if ($submitData===null)$submitData = $_POST;
        // if ($submitData===null)$submitData = $_GET;
        $data = $submitData;
        $form = $this->form($formName);
        
        $inputs = $form->getInputs();
        // echo 'this is where we submit... i guess.';
        // echo implode("\n",$inputs);
        
        $saveData = [];
        foreach ($inputs as $input){
            $name = $input->name;
            if (isset($submitData[$name])){
                $value = $submitData[$name];
                $filteredValue = $this->filter($name,$value,$input);
                $saveData[$name][] = $filteredValue;
                unset($submitData[$name]);
            }
        }
        $table = $submitData['fresh_table'] ?? null;
            unset($submitData['fresh_table']);
        $id = $submitData['id'] ?? null;
            unset($submitData['id']);
        
        if (count($submitData)>0){
            throw new \Exception("There was more data submitted than the form allows.");
        }
        if ($id!==null)$saveData['id'][] = $id;
        if ($table==null)throw new \Exception("Cannot autosubmit form because either table is null.");


        $submitter = $this->submitHandler;

        if ($submitter==null){
            throw new \Exception("There is no submitter. Call setSubmitHandler(\$callback);... "
                                ."where \$callback accepts: string \$tableName, array \$dataToSave, string|int \$itemId. "
                                ."");
        }
        return $submitter($table,$saveData,$id,$passthru);
    }
    static public function makeCompo($dir){
        
    }
    public function setFilterHandler($callback){
        $this->filterHandler = $callback;
    }
    public function setSubmitHandler($callback){
        $this->submitHandler = $callback;
    }
    public function addRuntimeHandler($name,$callback){
        $this->runtimeHandlers[] = ['name'=>$name,'callback'=>$callback];
    }
    public function addCompileHandler($name,$callback){
        $this->compileHandlers[] = ['name'=>$name,'callback'=>$callback];
    }
    public function addViewQuery($query,$callback){
        $this->viewQueries[] = ['query'=>$query,'callback'=>$callback];
    }
    public function compileViews($forceRecompile=false){
        $views = $this->viewNames();
        foreach ($views as $name){
            $v = $this->view($name);
            foreach($this->viewQueries as $index=>$info){
                $query = $info['query'];
                $callback = $info['callback'];
                $v->addQuery($query,$callback);

            }
            foreach($this->runtimeHandlers as $index=>$info){
                $name = $info['name'];
                $callback = $info['callback'];
                $v->addRuntimeHandler($name,$callback);
            }
            foreach($this->compileHandlers as $index=>$info){
                $name = $info['name'];
                $callback = $info['callback'];
                $v->addCompileHandler($name,$callback);
            }
            $v->compile($forceRecompile);
        }
    }
    public function compileForms($forceRecompile=false){
        $views = $this->viewNames();
        foreach ($views as $name){
            $v = $this->form($name);
            $v->setView($this->view($name));
            // echo "set view";
            foreach($this->formQueries as $index=>$info){
                $query = $info['query'];
                $callback = $info['callback'];
                $v->addQuery($query,$callback);
            }
            foreach($this->runtimeHandlers as $index=>$info){
                $name = $info['name'];
                $callback = $info['callback'];
                $v->addRuntimeHandler($name,$callback);
            }
            foreach($this->compileHandlers as $index=>$info){
                $name = $info['name'];
                $callback = $info['callback'];
                $v->addCompileHandler($name,$callback);
            }
            $v->compile($forceRecompile);
        }
    }
    public function setup($passthru=[]){
        $views = $this->viewNames();
        foreach ($views as $name){
            $v = $this->view($name);
            $v->setup($passthru);
            $f = $this->form($name) ?? null;
            if ($f!=null)$f->setup($passthru);
        }
    }
}